feat: create relationship import system#45
Conversation
…sable component to use it on main page and while onboarding
There was a problem hiding this comment.
Pull request overview
Implements an admin-facing bulk import workflow for competency relationships (CSV/JSON), alongside a broader shift to Keycloak-backed authentication/authorization and a new admin panel surface for moderation and role management.
Changes:
- Added admin UI pages for moderation, importing competencies/relationships, role management, and export placeholder.
- Introduced Keycloak auth integration on the client (AuthProvider, protected/admin routes, axios bearer token injection).
- Added server-side admin import endpoints + import DTOs/results, plus
/api/auth/me, JWT resource server config, and user schema updates for Keycloak UUID subjects.
Reviewed changes
Copilot reviewed 49 out of 51 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pages/SessionPage.tsx | Switches demo-user bootstrap to fetch current authenticated user. |
| src/pages/RolesPage.tsx | New admin UI to view users and toggle roles. |
| src/pages/RelationshipImportPage.tsx | New UI for relationship bulk import via file upload or JSON paste. |
| src/pages/OnboardingPage.tsx | Integrates auth state into onboarding flow; persists some fields in sessionStorage; adds privacy-policy link. |
| src/pages/ModerationPage.tsx | New admin UI for inline editing and deleting competencies/resources. |
| src/pages/ImportPage.tsx | New UI for competency bulk import via file upload or JSON paste. |
| src/pages/HomePage.tsx | Start button now navigates based on auth + onboarded status. |
| src/pages/ExportPage.tsx | New “Export” placeholder page in admin area. |
| src/pages/DashboardPage.tsx | Uses authenticated userId for stats instead of guest constant. |
| src/pages/AdminPage.tsx | New admin panel landing page with cards to admin tools. |
| src/lib/auth/keycloak.ts | Adds Keycloak client initialization (check-sso, PKCE, silent SSO). |
| src/lib/api/types.ts | Adds ImportResult + RelationshipImportRow; expands relationshipType union with UNRELATED; adds degree to Competency. |
| src/lib/api/session-helpers.ts | Adds /api/auth/me helper for retrieving current user. |
| src/lib/api/client.ts | Adds axios request interceptor to attach Bearer token and refresh token when needed. |
| src/lib/api/admin.ts | New admin API client for import endpoints (JSON + file). |
| src/index.css | Extends CSS custom properties for theme colors. |
| src/contexts/useAuth.ts | New hook for accessing AuthContext. |
| src/contexts/auth-context.ts | Defines AuthContextValue and creates AuthContext. |
| src/contexts/AuthContext.tsx | New AuthProvider that initializes Keycloak, syncs /api/auth/me, and exposes auth state/actions. |
| src/components/navbar.tsx | Shows sign-in/out + admin link based on auth/role; updates gradient class usage. |
| src/components/ProtectedRoute.tsx | New route guard requiring authentication (and handling domain denial). |
| src/components/AdminRoute.tsx | New route guard requiring ADMIN role. |
| src/App.tsx | Wraps app in AuthProvider; adds protected and admin route structure + new pages. |
| server/src/main/resources/db/migration/V9__update_users_for_keycloak_auth.sql | Alters users table for Keycloak subjects and adjusts one FK column length. |
| server/src/main/resources/application.yml | Configures OAuth2 resource server JWT, multipart limits, Flyway settings, and allowed email domain list. |
| server/src/main/java/de/tum/cit/memo/service/UserService.java | Adds find-or-create by Keycloak subject. |
| server/src/main/java/de/tum/cit/memo/service/CompetencyService.java | Adds bulk import logic for competencies with per-row validation/skip. |
| server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java | Adds bulk relationship import with title/id resolution, duplicate skipping, and optional vote seeding. |
| server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java | Switches API to JWT-authenticated resource server; restricts admin and delete routes. |
| server/src/main/java/de/tum/cit/memo/security/DbRoleJwtAuthenticationConverter.java | Maps authorities from DB role keyed by JWT subject. |
| server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java | Adds existsByTitle and findByTitle. |
| server/src/main/java/de/tum/cit/memo/entity/User.java | Makes name/email nullable and expands id length to 36. |
| server/src/main/java/de/tum/cit/memo/dto/RelationshipImportRow.java | DTO for relationship import rows. |
| server/src/main/java/de/tum/cit/memo/dto/ImportResult.java | Record for import result summary. |
| server/src/main/java/de/tum/cit/memo/dto/CompetencyImportRow.java | DTO for competency import rows. |
| server/src/main/java/de/tum/cit/memo/controller/AuthController.java | Adds /api/auth/me to enforce domain allowlist + sync user record. |
| server/src/main/java/de/tum/cit/memo/controller/AdminController.java | Adds admin import endpoints for competencies and relationships; implements CSV/JSON parsing. |
| server/src/main/java/de/tum/cit/memo/config/MemoProperties.java | Adds memo.allowed-email-domains config binding. |
| server/src/main/java/de/tum/cit/memo/MemoApiApplication.java | Enables configuration properties scanning. |
| server/docker/keycloak/memo-realm.json | Updates Keycloak realm config (protocol mapper for email; SMTP config; removes seeded users). |
| server/docker-compose.yml | Adds Mailpit; configures Keycloak + API + DB containers; adjusts Keycloak issuer env. |
| server/build.gradle | Adds Spring OAuth2 resource server dependency. |
| sample-data/relationships-sample.json | Adds sample relationship import JSON. |
| sample-data/relationships-sample.csv | Adds sample relationship import CSV. |
| sample-data/competencies-sample.json | Adds sample competency import JSON. |
| sample-data/competencies-sample.csv | Adds sample competency import CSV. |
| public/silent-check-sso.html | Adds Keycloak silent SSO callback page. |
| postcss.config.mjs | Removed config file (repo retains postcss.config.js). |
| package-lock.json | Dependency lockfile updates. |
| auth-flow.svg | Adds auth flow diagram (SVG). |
| auth-flow.mmd | Adds auth flow diagram (Mermaid source). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
…c' into feature/43-feat-create-relationship-import-system
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
MaximilianAnzinger
left a comment
There was a problem hiding this comment.
Please have a look at the merge conflict
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
Description
Implements a bulk import system for competency relationships, allowing admins to create multiple relationships at once from a JSON or CSV file. Relationships can be referenced by competency ID or title, with an optional seed vote on import.
Type of Change
expected)
Related Issues
Changes Made
RelationshipImportPageat/admin/import/relationshipswith file upload (drag-and-drop) and JSON paste modesimportRelationshipsJsonandimportRelationshipsFilemethods toadminApiRelationshipImportRowinterface totypes.ts; fixedCompetencyRelationship.relationshipTypeunion to includeUNRELATEDRelationshipImportRowDTO supportingoriginId/originTitle,destinationId/destinationTitle, and optionalrelationshipTypebulkImportRelationships()toCompetencyRelationshipServicewith per-row validation, title-to-ID resolution, duplicate skipping, and optional vote seedingfindByTitle()toCompetencyRepositoryPOST /api/admin/relationships/import(JSON) andPOST /api/admin/relationships/import/file(CSV/JSON) toAdminControllerwith dynamic header-based CSV parsingsample-data/relationships-sample.jsonandrelationships-sample.csvfor manual testingTesting
Test Cases
Manual Testing
Verified the following scenarios via the Import Relationships UI and the provided sample files:
relationshipType— vote seeded on the corresponding counter, entropy recalculatedrelationshipType— relationship created with zero votesskipped, noterrorsImportResult.errorsrelationshipType— per-row error returnedScreenshots/Videos
Before
After